package org.example.ding.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 点餐记录实体类
 * 记录用户的点餐历史和实际营养摄入
 */
@Entity
@Table(name = "order_records", indexes = {
    @Index(name = "idx_user_date", columnList = "user_id, order_date"),
    @Index(name = "idx_meal_type", columnList = "meal_type")
})
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderRecord {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    @NotNull(message = "用户不能为空")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "dish_id", nullable = false)
    @NotNull(message = "菜品不能为空")
    private Dish dish;

    @Enumerated(EnumType.STRING)
    @Column(name = "meal_type", nullable = false)
    @NotNull(message = "餐别不能为空")
    private MealType mealType;

    @DecimalMin(value = "0.1", message = "份量必须大于0.1")
    @DecimalMax(value = "10.0", message = "份量不能超过10")
    @Column(name = "portion_size", precision = 5, scale = 2)
    private BigDecimal portionSize = BigDecimal.ONE;

    @Column(name = "order_date", nullable = false)
    @NotNull(message = "点餐日期不能为空")
    private LocalDate orderDate;

    @CreationTimestamp
    @Column(name = "order_time")
    private LocalDateTime orderTime;

    // 实际营养摄入 (根据份量计算)
    @DecimalMin(value = "0.0", message = "实际卡路里必须大于等于0")
    @Column(name = "actual_calories", precision = 8, scale = 2)
    private BigDecimal actualCalories;

    @DecimalMin(value = "0.0", message = "实际蛋白质必须大于等于0")
    @Column(name = "actual_protein", precision = 8, scale = 2)
    private BigDecimal actualProtein;

    @DecimalMin(value = "0.0", message = "实际碳水化合物必须大于等于0")
    @Column(name = "actual_carbs", precision = 8, scale = 2)
    private BigDecimal actualCarbs;

    @DecimalMin(value = "0.0", message = "实际脂肪必须大于等于0")
    @Column(name = "actual_fat", precision = 8, scale = 2)
    private BigDecimal actualFat;

    /**
     * 餐别类型枚举
     */
    public enum MealType {
        BREAKFAST("早餐"),
        LUNCH("午餐"),
        DINNER("晚餐"),
        SNACK("小食");

        private final String description;

        MealType(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 计算实际营养摄入
     * 在保存前自动计算
     */
    @PrePersist
    @PreUpdate
    public void calculateActualNutrition() {
        if (dish != null && portionSize != null) {
            // 调试日志
            System.out.println("计算营养 - 菜品: " + dish.getName() + ", 份量: " + portionSize);
            System.out.println("菜品基础营养 - 卡路里: " + dish.getCalories() + ", 蛋白质: " + dish.getProtein() +
                             ", 碳水: " + dish.getCarbohydrates() + ", 脂肪: " + dish.getFat());

            Dish.NutritionInfo nutrition = dish.calculateNutrition(portionSize);
            this.actualCalories = nutrition.getCalories();
            this.actualProtein = nutrition.getProtein();
            this.actualCarbs = nutrition.getCarbohydrates();
            this.actualFat = nutrition.getFat();

            System.out.println("计算后实际营养 - 卡路里: " + actualCalories + ", 蛋白质: " + actualProtein +
                             ", 碳水: " + actualCarbs + ", 脂肪: " + actualFat);
        }
    }

    /**
     * 设置当前日期为点餐日期
     */
    public void setOrderDateToToday() {
        this.orderDate = LocalDate.now();
    }

    /**
     * 构造函数 - 创建新的点餐记录
     */
    public OrderRecord(User user, Dish dish, MealType mealType, BigDecimal portionSize) {
        this.user = user;
        this.dish = dish;
        this.mealType = mealType;
        this.portionSize = portionSize != null ? portionSize : BigDecimal.ONE;
        this.orderDate = LocalDate.now();
        calculateActualNutrition();
    }

    /**
     * 获取总营养摄入
     */
    public BigDecimal getTotalNutrition() {
        BigDecimal total = BigDecimal.ZERO;
        if (actualCalories != null) total = total.add(actualCalories);
        if (actualProtein != null) total = total.add(actualProtein.multiply(BigDecimal.valueOf(4))); // 蛋白质 4 卡/克
        if (actualCarbs != null) total = total.add(actualCarbs.multiply(BigDecimal.valueOf(4))); // 碳水 4 卡/克
        if (actualFat != null) total = total.add(actualFat.multiply(BigDecimal.valueOf(9))); // 脂肪 9 卡/克
        return total;
    }
}
